package com.fingard.dsp.bank.directbank.fuiou01;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.fingard.constant.Format;
import com.fingard.crypto.DigestHelper;
import com.fingard.dsp.bank.directConfig.ActSetItem;
import com.fingard.dsp.bank.directbank.FailCode;
import com.fingard.dsp.bank.directbank.RefundState;
import com.fingard.dsp.bank.directbank.bankInterface.IRecRefund;
import com.fingard.dsp.bank.reqrespobj.recrefund.ReqQryRecRefund;
import com.fingard.dsp.bank.reqrespobj.recrefund.ReqRecRefund;
import com.fingard.dsp.bank.reqrespobj.recrefund.RetAtsQryRecRefund;
import com.fingard.dsp.bank.reqrespobj.recrefund.RetAtsRecRefund;
import com.fingard.net.ConnState;
import com.fingard.text.StringHelper;
import com.fingard.xml.XmlTextReader;
import com.fingard.xml.XmlTextWriter;

import java.util.Date;


public class FUIOU01RecRefund extends FUIOU01Base implements IRecRefund {
    @Override
    public RetAtsRecRefund submitRecRefund(ReqRecRefund p_reqRef) throws Exception {
        RetAtsRecRefund retAts = new RetAtsRecRefund();
        retAts.oriRdSeq = p_reqRef.oriRdSeq;//原商户订单号
        retAts.refundNo = p_reqRef.refundNo;//退款流水号
            if (p_reqRef.orderType.equals("ALIPAY")||p_reqRef.orderType.equals("WECHAT"))
            {
                return submitRecRefund01(p_reqRef);
            }else if (p_reqRef.orderType.equals("BankCard")){
                return submitRecRefund02(p_reqRef);
            }else{
                retAts.respCode = "-1";
                retAts.respInfo = "未找到[" + p_reqRef.orderType + "]订单类型!";
                return retAts;
            }
    }

    public RetAtsRecRefund submitRecRefund01(ReqRecRefund p_reqRef) throws Exception {
        RetAtsRecRefund retAts = new RetAtsRecRefund();
        retAts.oriRdSeq = p_reqRef.oriRdSeq;//原商户订单号
        retAts.refundNo = p_reqRef.refundNo;//退款流水号
        try {
            ActSetItem actItem = this.getBankConfig().getActSetItem(p_reqRef.ownAct, "ZFBWX");
            if (actItem != null) {
                JSONObject postParams = new JSONObject();
                //版本号
                postParams.put("version", "1.0");
                //商户代码
                postParams.put("mchnt_cd", actItem.merchantId);
                //终端号  term_id
                postParams.put("term_id", actItem.termId);
                //随机字符串
                String nonce_str = get_nonce_str();
                postParams.put("random_str", nonce_str);
                //商户订单号mchnt_order_no
                String outTradeNo = p_reqRef.oriRdSeq;
                postParams.put("mchnt_order_no", outTradeNo);
                //退款单号
                String refundNo = p_reqRef.refundNo;
                postParams.put("refund_order_no", refundNo);
                //订单类型
                postParams.put("order_type",p_reqRef.orderType);

                //订单金额 total_amt
                postParams.put("total_amt", StringHelper.amountMultiply100(p_reqRef.totalAmt));
                //退款金额 refund_amt
                postParams.put("refund_amt", StringHelper.amountMultiply100(p_reqRef.amount));

                //操作员 operator_id
                postParams.put("operator_id", this.bankFront.operator);
                //富友终端号 reserved_fy_term_ id actItem.saltKey
                postParams.put("reserved_fy_term_id", this.bankFront.termid);
                postParams.put("reserved_origi_dt", p_reqRef.oriPayDate);

                String reqStr =actItem.merchantId + "|" + p_reqRef.orderType + "|" + p_reqRef.oriRdSeq + "|"  + p_reqRef.refundNo + "|" + StringHelper.amountMultiply100(p_reqRef.totalAmt) + "|"
                        + StringHelper.amountMultiply100(p_reqRef.amount)  + "|" +actItem.termId + "|" + nonce_str + "|"  +"1.0" + "|"+ actItem.saltKey;
                String sign = DigestHelper.cryptoMD5RetHexStr(reqStr.getBytes(getCharset()));
                postParams.put("sign", sign);
                String tmpReqStr = JSON.toJSONString(postParams);
//                FuiouHttpPoster http = new FuiouHttpPoster();
//                http.setCharset("utf-8");
//                http.setUrl("http://192.168.8.45:45002/aggregatePay/commonRefund");
//                RefundDataReq req = new RefundDataReq();
//                req.setVersion("1.0");
//                req.setMchnt_cd("0002900F0370586");
//                req.setTerm_id("0a1b0000");
//                req.setRandom_str("123456");
//                req.setMchnt_order_no("10662019040600000001");
//                req.setRefund_order_no("1066BD20190400000000000011");
//                req.setOrder_type("WECHAT");
//                req.setTotal_amt("1");
//                req.setRefund_amt("1");
//                StringBuilder sb = new StringBuilder();

////                sb.append(req.getMchnt_cd()).append("|").append(req.getOrder_type()).append("|")
////                        .append(req.getMchnt_order_no()).append("|").append(req.getRefund_order_no())
////                        .append("|").append(req.getTotal_amt()).append("|").append(req.getRefund_amt())
////                        .append("|").append(req.getTerm_id()).append("|").append(req.getRandom_str())
////                        .append("|").append(req.getVersion()).append("|").append(privateKey);
////                System.out.println("请求sign："+ sb.toString());
//               req.setSign(MD5.MD5Encode(sb.toString(), "UTF-8"));
                //String res = http.newPost(JSON.toJSONString(req));
                //System.out.println(res);
                //String p_for="refundreq_"+p_reqRef.ownAct;
                String[] tmpStrRet = sendToBank("refundreqzfb", tmpReqStr);
                if (tmpStrRet[0].length() == 0) {
                    JSONObject tmpRespJson = JSONObject.parseObject(tmpStrRet[1]);
                    String tmpRespCode = tmpRespJson.getString("result_code");
                    String tmpRespInfo = tmpRespJson.getString("result_msg");
                    if (tmpRespCode.equals("000000")) {
                        retAts.respCode = "0";
                        retAts.respInfo = tmpRespInfo;
                        //渠道流水号 transaction_id
                        retAts.oriOppOrderNo = tmpRespJson.getString("transaction_id");
                        retAts.originalCode = tmpRespJson.getString("result_code");
                        retAts.originalInfo = tmpRespJson.getString("result_msg");
                        retAts.unifiedCode = getBankConfig().getMapValueByKey("recRefundMapping", retAts.originalCode);
                        if ("000000".equals(retAts.originalCode)) {
                            retAts.refundState = RefundState.REFUND_SUCCESS;
                        } else {
                            retAts.refundState = RefundState.REFUND_PAYING;
                        }
                    }else {
                        retAts.respCode = "-1";
                        retAts.respInfo = tmpRespInfo;
                    }
                } else if (tmpStrRet[0].equals(ConnState.FAIL) || tmpStrRet[0].equals(FailCode.E9981)) {
                    retAts.respCode = "0";
                    retAts.respInfo = tmpStrRet[1];
                } else {
                    retAts.respCode = "-1";
                    retAts.respInfo = tmpStrRet[1];
                }
            } else {
                retAts.respCode = "-1";
                retAts.respInfo = "未找到账号[" + p_reqRef.ownAct + "]商户配置信息!";
            }
        } catch (Exception ex) {
            ex.printStackTrace();
            retAts.respCode = "0";
            retAts.respInfo = ex.getMessage();
            WriteBankLogLn(ex);
        }
        return retAts;
    }
    public RetAtsRecRefund submitRecRefund02(ReqRecRefund p_reqRef) throws Exception {
        RetAtsRecRefund retAts = new RetAtsRecRefund();
        retAts.oriRdSeq = p_reqRef.oriRdSeq;//原商户订单号
        retAts.refundNo = p_reqRef.refundNo;//退款流水号
        try {

            ActSetItem actItem = getBankConfig().getActSetItem(p_reqRef.ownAct, "WY");
            if (actItem != null) {
                XmlTextWriter xmlWriter = new XmlTextWriter();
                xmlWriter.autoFormat=false;
                xmlWriter.writeStartDocByDeclaration("<?xml version=\"1.0\" encoding=\"" + getCharset() + "\"?>");
                xmlWriter.writeStartElement("REFUND");
                xmlWriter.writeStartElement("HEADER");
                xmlWriter.writeElementString("MCHNT_CD", actItem.merchantId);
                xmlWriter.writeElementString("REFUND_SSN", p_reqRef.refundNo);
                xmlWriter.writeElementString("CALL_BACK_URL", bankFront.getUrl("refundCallbackUrl"));
                String reqStr =actItem.merchantId + "|" + p_reqRef.refundNo + "|" + actItem.saltKey;
                String sign = DigestHelper.cryptoMD5RetHexStr(reqStr.getBytes(getCharset()));
                xmlWriter.writeElementString("SIGN", sign);
                xmlWriter.writeEndElement();
                xmlWriter.writeStartElement("BODY");
                xmlWriter.writeStartElement("ORDER");
                xmlWriter.writeElementString("APPLY_DT", Format.Date8Format.format(new Date()));
                xmlWriter.writeElementString("TRACE_NO", p_reqRef.refundNo);
                xmlWriter.writeElementString("REFUND_AMT", StringHelper.amountMultiply100(p_reqRef.amount) );
                    xmlWriter.writeElementString("FY_DATE", p_reqRef.oriPayDate);
                    xmlWriter.writeElementString("FY_SSN",p_reqRef.oriRdSeq);
                    xmlWriter.writeEndElement();
                    //xmlWriter.writeEndElement();
                    xmlWriter.writeEndDocument();

                String[] tmpStrRet = sendToBank("refundreqwy", xmlWriter.toXmlString(),true);
                if (tmpStrRet[0].length() == 0) {
                    //JSONObject tmpRespJson = JSONObject.parseObject(tmpStrRet[1]);
                    StringBuilder tmpSbMsg = new StringBuilder();
                    XmlTextReader tmpBkReader = loadBankRespXmlReader(tmpStrRet[1], tmpSbMsg);

                    if (tmpBkReader != null) {
                        String return_code = tmpBkReader.getFirstText("/REFUND/BODY/ORDER/RSP_CODE");
                        String return_msg = tmpBkReader.getFirstText("/REFUND/BODY/ORDER/RSP_MSG");
                        retAts.respInfo = return_msg;
                        if (return_code != null && return_code.equals("0000")) {
                        	retAts.respCode = "0";
                            retAts.oriOppOrderNo = tmpBkReader.getFirstText("/REFUND/BODY/ORDER/FY_SSN");
                            retAts.oppRefundNo = tmpBkReader.getFirstText("/REFUND/BODY/ORDER/TRACE_NO");
                            retAts.originalCode = return_code;
                            retAts.originalInfo = return_msg;
                            retAts.unifiedCode = getBankConfig().getMapValueByKey("recRefundMapping", retAts.originalCode);
                            if ("0000".equals(retAts.originalCode)) {
                                retAts.refundState = RefundState.REFUND_SUCCESS;
                            } else {
                                retAts.refundState = RefundState.REFUND_PAYING;
                            }

                        } else {
                            retAts.respCode = "-1";
                            retAts.respInfo = return_msg;
                        }
                    }
                } else {
                    retAts.respCode = "-1";
                    retAts.respInfo = tmpStrRet[1];
                }

            } else {
                retAts.respCode = "-1";
                retAts.respInfo = "未找到账号[" + p_reqRef.ownAct + "]商户配置信息!";
            }
        } catch (Exception ex) {
            ex.printStackTrace();
            retAts.respCode = "0";
            retAts.respInfo = ex.getMessage();
            WriteBankLogLn(ex);
        }
        return retAts;
    }

    @Override
    public RetAtsQryRecRefund queryRecRefund(ReqQryRecRefund p_reqQryRef) throws Exception {
        RetAtsQryRecRefund retAts = new RetAtsQryRecRefund();
        retAts.oriRdSeq = p_reqQryRef.oriRdSeq;
        retAts.refundNo = p_reqQryRef.refundNo;

        if (p_reqQryRef.orderType.equals("ALIPAY")||p_reqQryRef.orderType.equals("WECHAT"))
            {
                return queryRecRefund01(p_reqQryRef);
            }else if (p_reqQryRef.orderType.equals("BankCard")){
                //网银
                return queryRecRefund02(p_reqQryRef);
            }
            else{
            retAts.respCode = "-1";
            retAts.respInfo = "未找到[" + p_reqQryRef.orderType + "]订单类型!";
            return retAts;
        }
    }

    public RetAtsQryRecRefund queryRecRefund01(ReqQryRecRefund p_reqQryRef) throws Exception {
        RetAtsQryRecRefund retAts = new RetAtsQryRecRefund();
        retAts.oriRdSeq = p_reqQryRef.oriRdSeq;
        retAts.refundNo = p_reqQryRef.refundNo;
        try {
            ActSetItem actItem = this.getBankConfig().getActSetItem(p_reqQryRef.ownAct, "ZFBWX");
            if (actItem != null) {
                JSONObject postParams = new JSONObject();
                //版本号
                postParams.put("version", "1.0");
                //商户号mchnt_cd
                String mch_id = actItem.merchantId;
                postParams.put("mchnt_cd", mch_id);
                //随机字符串random_str
                String nonce_str = get_nonce_str();
                postParams.put("random_str", nonce_str);
                //终端号 term_id
                postParams.put("term_id", actItem.termId);
                //退款单号 refund_order_no  和流水号
                String refundNo = p_reqQryRef.refundNo;
                postParams.put("refund_order_no" ,refundNo);
                String reqStr = actItem.merchantId + "|" + refundNo + "|" + actItem.termId+ "|"  + nonce_str + "|" + "1.0" + "|"
                        + actItem.saltKey;
                String sign = DigestHelper.cryptoMD5RetHexStr(reqStr.getBytes(getCharset()));
                postParams.put("sign", sign);
                String tmpStrReq = JSON.toJSONString(postParams);

                String[] tmpStrRet = sendToBank("refundqryzfb", tmpStrReq);
                if (tmpStrRet[0].length() == 0) {
                    JSONObject tmpRespJson = JSONObject.parseObject(tmpStrRet[1]);
                    String tmpRespCode = tmpRespJson.getString("result_code");
                    String tmpRespInfo = tmpRespJson.getString("result_msg");
                    if ("000000".equals(tmpRespCode)) {
                        retAts.respCode = "0";
                        retAts.respInfo = tmpRespInfo;
                        String status = tmpRespJson.getString("trans_stat");
                        if ("SUCCESS".equals(status)) {
                            retAts.refundState = RefundState.REFUND_SUCCESS;
                        } else if("PAYERROR".equals(status)){
                            retAts.refundState = RefundState.REFUND_FAIL;
                        }else {
                            retAts.refundState = RefundState.REFUND_PAYING;
                        }
                        retAts.oriOppOrderNo = tmpRespJson.getString("refund_order_no");
                        retAts.originalCode = tmpRespJson.getString("result_code");
                        retAts.originalInfo = tmpRespJson.getString("result_msg");
                        retAts.unifiedCode = getBankConfig().getMapValueByKey("recRefundMapping", retAts.originalCode);
                    }else {
                        retAts.respCode = "-1";
                        retAts.respInfo = tmpRespInfo;
                    }
                } else {
                    retAts.respCode = "-1";
                    retAts.respInfo = tmpStrRet[1];
                }
            } else {
                retAts.respCode = "-1";
                retAts.respInfo = "未找到账号[" + p_reqQryRef.ownAct + "]商户配置信息!";
            }
        } catch (Exception ex) {
            ex.printStackTrace();
            retAts.respCode = "-1";
            retAts.respInfo = ex.getMessage();
            WriteBankLogLn(ex);
        }
        return retAts;
    }
    public RetAtsQryRecRefund queryRecRefund02(ReqQryRecRefund p_reqQryRef) throws Exception {
        RetAtsQryRecRefund retAts = new RetAtsQryRecRefund();
        retAts.oriRdSeq = p_reqQryRef.oriRdSeq;
        retAts.refundNo = p_reqQryRef.refundNo;
        try {
            ActSetItem actItem = this.getBankConfig().getActSetItem(p_reqQryRef.ownAct, "WY");
            if (actItem != null) {
                StringBuilder sbXml = new StringBuilder();
                sbXml.append("<REFUND>\r\n");
                sbXml.append("<HEADER>\r\n");
                sbXml.append("<MCHNT_CD>" + actItem.merchantId + "</MCHNT_CD>\r\n");
                //查询仅需商户|密钥进行签名
                String reqStr = actItem.merchantId + "|" + actItem.saltKey;//+ "|" + p_reqQryRef.refundNo
                String sign = DigestHelper.cryptoMD5RetHexStr(reqStr.getBytes(getCharset()));
                sbXml.append("<SIGN>" + sign + "</SIGN>\r\n");
                sbXml.append("</HEADER>");
                sbXml.append("<BODY>\r\n");
                sbXml.append("<ORDER>\r\n");
                sbXml.append("<APPLY_DT>" + p_reqQryRef.payDate + "</APPLY_DT>\r\n");
                sbXml.append("<TRACE_NO>" + p_reqQryRef.refundNo + "</TRACE_NO>\r\n");
                sbXml.append("</ORDER>");
                sbXml.append("</BODY>");
                sbXml.append("</REFUND>");
                String[] tmpStrRet = sendToBank("refundqrywy", sbXml.toString(), true);
                if (tmpStrRet[0].length() == 0) {
                    //JSONObject tmpRespJson = JSONObject.parseObject(tmpStrRet[1]);
                    StringBuilder tmpSbMsg = new StringBuilder();
                    XmlTextReader tmpBkReader = loadBankRespXmlReader(tmpStrRet[1], tmpSbMsg);
                    if (tmpBkReader != null) {
                        String return_code = tmpBkReader.getFirstText("/REFUND/BODY/ORDER/RSP_CODE");
                        String return_msg = tmpBkReader.getFirstText("/REFUND/BODY/ORDER/RSP_MSG");
                        retAts.respInfo = return_msg;
                        if (return_code != null && return_code.equals("0000")) {
                        	retAts.respCode = "0";
                            retAts.oriOppOrderNo = tmpBkReader.getFirstText("/REFUND/BODY/ORDER/FY_SSN");
                            retAts.oppRefundNo = tmpBkReader.getFirstText("/REFUND/BODY/ORDER/TRACE_NO");
                            retAts.originalCode = return_code;
                            retAts.originalInfo = return_msg;
                            retAts.unifiedCode = getBankConfig().getMapValueByKey("recRefundMapping", retAts.originalCode);

                            if ("0000".equals(retAts.originalCode)) {
                                retAts.refundState = RefundState.REFUND_SUCCESS;
                            } else {
                                retAts.refundState = RefundState.REFUND_PAYING;
                            }

                        } else {
                            retAts.respCode = "-1";
                            retAts.respInfo = return_msg;
                        }
                    }
                } else {
                    retAts.respCode = "-1";
                    retAts.respInfo = tmpStrRet[1];
                }
            }
            else {
                retAts.respCode = "-1";
                retAts.respInfo = "未找到账号[" + p_reqQryRef.ownAct + "]商户配置信息!";
            }
        } catch (Exception ex) {
            ex.printStackTrace();
            retAts.respCode = "-1";
            retAts.respInfo = ex.getMessage();
            WriteBankLogLn(ex);
        }
        return retAts;
    }
}
